package com.hm.hall.commons.util;

import com.alibaba.fastjson.JSONObject;
import org.apache.commons.lang.StringUtils;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.io.Reader;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.util.Enumeration;

public class IPUtil {

    /**
     * 获得ip地址, 取不到 返回0.0.0.0
     */
    public static String getIpAddr() {
        try {
            String ip = getIpAddr(ActionUtils.getRequest());
            return StringUtils.isBlank(ip) ? "0.0.0.0" : ip;
        } catch (Exception e) {
            return "0.0.0.0";
        }
    }
    
/*    public static String getIpAddrByWebSocket(WebSocketSession webSocketSession) {
          HttpHeaders headers =  webSocketSession.getHandshakeHeaders();
    	  String ip = headers.getFirst("x-forwarded-for");
          if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
              ip = headers.getFirst("Proxy-Client-IP");
          }
          if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
              ip = headers.getFirst("WL-Proxy-Client-IP");
          }
          if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
              ip = webSocketSession.getRemoteAddress().getHostName();
          }
          //可是，如果通过了多级反向代理的话，X-Forwarded-For的值并不止一个，而是一串IP值，究竟哪个才是真正的用户端的真实IP呢？
          //   * 答案是取X-Forwarded-For中第一个非unknown的有效IP字符串。
          if (ip != null && ip.contains(",")) {
              ip = ip.split(",")[0];
          }
          return ip;
    }*/


    /**
     * 获得ip地址
     */
    public static String getIpAddr(HttpServletRequest request) {
        String ip = request.getHeader("x-forwarded-for");
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }
        //可是，如果通过了多级反向代理的话，X-Forwarded-For的值并不止一个，而是一串IP值，究竟哪个才是真正的用户端的真实IP呢？
        //   * 答案是取X-Forwarded-For中第一个非unknown的有效IP字符串。
        if (ip != null && ip.contains(",")) {
            ip = ip.split(",")[0];
        }
        return ip;
    }

    /**
     * 获取客户端源端口
     *
     * @param request
     * @return
     */
    public static Long getRemotePort(final HttpServletRequest request) {
        try {
            String port = request.getHeader("remote-port");
            if (null == port || "".equals(port)) {
                try {
                    return Long.parseLong(port);
                } catch (NumberFormatException ex) {
                    return 0L;
                }
            } else {
                return 0L;
            }
        } catch (Exception e) {
            return 0L;
        }
    }


    /**
     * 根据请求获取用户所在地
     */
    public static String getLocationByIp(HttpServletRequest request) {
        String ip = getIpAddr(request);
        return getLocationByIp(ip);
    }


    /**
     * 根据请求获取用户所在地   例: 广东省 深圳市
     */
    public static String getLocationByIp(String ip) {
        if (ip == null) {
            return "全国";
        } else {
            //根据ip地址获取地址信息有偏移，不是很准
            String url = "http://api.map.baidu.com/location/ip?ak=Nigm4hdtONcvsGNBr2fxPUFwAk08XQGq&ip=" + ip + "&coor=bd09ll";
            JSONObject jsonObject;
            try {
                String res = HttpRequestUtils.doGet(url);
                jsonObject = JsonUtils.parseObject(res);
                String status = jsonObject.getString("status");
                if ("0".equals(status)) {//通过ip可以获取地址
                    JSONObject contentJsonObject = jsonObject.getJSONObject("content");
                    JSONObject addrdJsonObject = contentJsonObject.getJSONObject("address_detail");
                    return addrdJsonObject.getString("province") + " " + addrdJsonObject.getString("city");
                } else {
                    return "全国";
                }
            } catch (Exception e) {
                e.printStackTrace();
                return "全国";
            }
        }
    }


    //将字节输入流转字符串
    private static String readAll(Reader rd) throws IOException {
        StringBuilder sb = new StringBuilder();
        int cp;
        while ((cp = rd.read()) != -1) {
            sb.append((char) cp);
        }
        return sb.toString();
    }


    /**
     * 获得主机IP
     *
     * @return String
     */
    public static boolean isWindowsOS() {
        boolean isWindowsOS = false;
        String osName = System.getProperty("os.name");
        if (osName.toLowerCase().indexOf("windows") > -1) {
            isWindowsOS = true;
        }
        return isWindowsOS;
    }

    /**
     * 获取本机ip地址，并自动区分Windows还是linux操作系统
     *
     * @return String
     */
    public static String getLocalIpAddr() {
        String sIP = "";
        InetAddress ip = null;
        try {
            //如果是Windows操作系统
            if (isWindowsOS()) {
                ip = InetAddress.getLocalHost();
            }
            //如果是Linux操作系统
            else {
                boolean bFindIP = false;
                Enumeration<NetworkInterface> netInterfaces = (Enumeration<NetworkInterface>) NetworkInterface
                        .getNetworkInterfaces();
                while (netInterfaces.hasMoreElements()) {
                    if (bFindIP) {
                        break;
                    }
                    NetworkInterface ni = (NetworkInterface) netInterfaces.nextElement();
                    //----------特定情况，可以考虑用ni.getName判断
                    //遍历所有ip
                    Enumeration<InetAddress> ips = ni.getInetAddresses();
                    while (ips.hasMoreElements()) {
                        ip = (InetAddress) ips.nextElement();
                        if (ip.isSiteLocalAddress()
                                && !ip.isLoopbackAddress()   //127.开头的都是lookback地址
                                && ip.getHostAddress().indexOf(":") == -1) {
                            bFindIP = true;
                            break;
                        }
                    }

                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        if (null != ip) {
            sIP = ip.getHostAddress();
        }
        return sIP;
    }

}
